﻿define(['util', 'ajax'], function (util, ajax) {
    "use strict";

    var exports = {},
       Column, Table, ViewModel;

    Column = function (data) {
        var self = this;
        self.editting = ko.observable(false);
        if (!data) {
            data = {
                propertyName: "",
                dataType: void 0,
                isUnique: false,
                isNull: false
            };
        }

        self.propertyName = ko.observable(data.propertyName).revertable();

        self.dataTypes = ko.observableArray([
            util.ko.getIdNamePair(0, "Guid"),
            util.ko.getIdNamePair(1, "Byte"),
            util.ko.getIdNamePair(2, "Boolean"),
            util.ko.getIdNamePair(3, "DateTime"),
            util.ko.getIdNamePair(4, "Enumeration"),
            util.ko.getIdNamePair(5, "String"),
            util.ko.getIdNamePair(6, "FixString"),
            util.ko.getIdNamePair(7, "UniString"),
            util.ko.getIdNamePair(8, "FxUniString"),
            util.ko.getIdNamePair(9, "Percentage"),
            util.ko.getIdNamePair(10, "Currency"),
            util.ko.getIdNamePair(11, "Integer"),
            util.ko.getIdNamePair(12, "Long"),
            util.ko.getIdNamePair(13, "Image")
        ]);

        self.dataType = ko.observable(data.dataType).revertable();

        self.size = ko.observableArray([
          { name: 1 },
          { name: 2 },
          { name: 4 },
          { name: 8 },
          { name: 16 },
          { name: 32 },
          { name: 64 },
          { name: 128 },
          { name: 256 },
          { name: 512 },
          { name: 1024 },
          { name: 2048 },
          { name: 4000 }
        ]);

        self.selectedSize = ko.observable(data.propertySize).revertable();

        self.sizeSelector = ko.observable(true);
        self.dataType.subscribe(function (newVal) {

            if (newVal == null) {
                self.sizeSelector(true);
                return;
            }

            switch (newVal) {
                case 0:
                    self.selectedSize(self.selectedSize(32));
                    self.sizeSelector(false);
                    break;
                case 1:
                case 2:
                    self.selectedSize(self.selectedSize(1));
                    self.sizeSelector(false);
                    break;
                case 4:
                    self.selectedSize(self.selectedSize(2));
                    self.sizeSelector(false);
                    break;
                case 3:
                case 9:
                case 10:
                case 11:
                case 12:
                    self.selectedSize(self.selectedSize(8));
                    self.sizeSelector(false);
                    break;
                case 13:
                    self.selectedSize(self.selectedSize(4096));
                    self.sizeSelector(false);
                    break;
                default:
                    self.selectedSize(self.selectedSize(256));
                    self.sizeSelector(true);
                    break;

            }

        });

        self.dataTypeName = ko.computed(function () {
            var pair = util.ko.findKoIdNamePair(self.dataTypes(), self.dataType());
            if (!pair) return "Undefined";
            return pair.name();
        }, this);

        self.isUnique = ko.observable(data.isUnique).revertable();
        self.isNull = ko.observable(data.isNull).revertable();

        self.revert = function () {
            self.propertyName.revert();
            self.isUnique.revert();
            self.isNull.revert();
            self.dataType.revert();
            self.selectedSize.revert();
        };

        self.commit = function () {
            self.propertyName.commit();
            self.isUnique.commit();
            self.isNull.commit();
            self.dataType.commit();
            self.selectedSize.commit();
        };

        self.edit = function (property, evt) {
            evt.preventDefault();
            self.editting(true);
        };

        self.cancel = function (property, evt) {
            evt.preventDefault();
            self.revert();
            self.editting(false);
        };

        self.update = function () {
            self.propertyName(self.propertyName());
            self.commit();
            self.editting(false);
        };
    };

    Table = function (data, selected) {
        var self = this;
        if (!data) {
            data = {
                tableName: "Add New",
                description: "",
                isAudited: false,
                hasName: false,
                hasThumbnail: false,
                hasDescription: false,
                columns: []
            };
        }

        self.tableName = ko.observable(data.tableName);
        self.description = ko.observable(data.description);

        self.isAudited = ko.observable(data.isAudited).revertable();
        self.hasName = ko.observable(data.hasName).revertable();
        self.hasDescription = ko.observable(data.hasDescription).revertable();
        self.hasThumbnail = ko.observable(data.hasThumbnail).revertable();

        self.columns = ko.observableArray([]);
        $.each(data.columns, function (row, val) {
            self.columns.push(new Column(val));
        });

        self.newColumn = ko.observable(new Column());

        self.createColumn = function (a) {
            var form = {
                propertyName: a.propertyName(),
                propertySize: a.selectedSize(),
                isNull: a.isNull(),
                isUnique: a.isUnique(),
                dataType: a.dataType()
            };
            var column = new Column(form);
            self.columns.push(column);
            self.newColumn(new Column());
        };

        self.deleteColumn = function (column) {
            self.columns.remove(column);
        };

        self.isSelected = ko.computed(function () {
            return self === selected();
        }, self);

        self.paneCss = ko.computed(function () {
            var css = "";
            if (self.isSelected()) {
                css += "btn";
            }
            return css;
        });

    };

    ViewModel = function (data) {
        var self = this;

        self.databaseName = ko.observable(data.databaseName);
        self.description = ko.observable(data.description);

        self.selectedTable = ko.observable();

        self.tables = ko.observableArray([new Table(null, self.selectedTable)]);

        $.each(data.tables, function (row, value) {
            self.tables.push(new Table(value, self.selectedTable));
        });

        self.cancelTable = function () {
            self.selectedTable(void 0);
        };

        self.saveTable = function (table) {
            var form = {
                TableName: table.tableName(),
                Description: table.description(),
                IsAudited: table.isAudited(),
                HasName: table.hasName(),
                HasDescription: table.hasDescription(),
                HasThumbnail: table.hasThumbnail(),
                columns: $.map(table.columns(), function (column) {
                    return {
                        PropertyName: column.propertyName(),
                        DataType: column.dataType(),
                        PropertySize: column.selectedSize(),
                        IsUnique: column.isUnique(),
                        IsNull: column.isNull()
                    };
                })
            };

            ajax.post('generator', form).done(function () {
                console.log(table);
                console.log(self.tables()[0]);
                if (table == self.tables()[0]) {
                    self.tables.unshift(new Table(null, self.selectedTable));
                }
            });
        };

        self.deleteTable = function (table) {
            ajax.del('generator', table.tableName()).done(function () {
                self.selectedTable(void 0);
                self.tables.remove(table);
            });
        };

        self.selectedTable(self.tables()[0]);
    };

    exports.exec = function (sectionId, model) {
        var viewModel = new ViewModel(model);
        ko.applyBindings(viewModel, document.getElementById(sectionId));
    };

    return exports;
});